#include "task.h"
#include "bsp_uart.h"
#include "bsp_time.h"
#include "string.h"
#include "bsp_gpio.h"


/***********************************************
函数名称：open_num_ad
函数参数: num打开指定回路
函数意义：
函数返回ֵ：
*************************************************/
void open_num_ad(uint8_t num)
{
	if((num > 0)&&(num <= 128))
	{
		write_74hc154(((num-1)%16)+1);
		write_74hc138(((num-1)/16)+1);
	}
}
/***********************************************
函数名称：open_num_ad
函数参数: num打开指定回路
函数意义：
函数返回ֵ：
*************************************************/
void close_num_ad(void)
{
	HC138_EN(0);
}

//冒泡排序函数
void Bubble_Sort(uint32_t *a,int len)
{
    int i=0;
    int j;
    int t;
    for(i=0;i<len-1;i++)
    {
        for(j=0;j<len-i-1;j++)
        {
            if(a[j]>a[j+1])
            {
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
        }
    }
}
//数据处理，此处是取中间的6个数值取平均数，排除最大值最小值的影响
uint32_t Data_Processing(uint32_t *buf,uint16_t len)
{
    int num = 0;
    uint32_t sum = 0;
    int average = 0;
    Bubble_Sort(buf,len);//进行排序计算
    num = len/2;//找出全部数据的中间
    //取中间的6组数据计算和
    sum = *(buf+num-2)+*(buf+num-1)+*(buf+num)+*(buf+num+1)+*(buf+num+2)+*(buf+num+3);
    average = sum/6;//求平均数并返回平均数
    return average;
}
/***********************************************
函数名称：uart_cmd01
函数参数: 
函数意义：串口接收到01命令处理，打开指定的回路继电器，
		在这里需要进行把之前的状态都关闭，然后在打开指定的回路。
函数返回ֵ：
*************************************************/
static void uart_cmd01(void)
{
	uint16_t addr = 0;
	uint8_t buf[20] = {0xef,0xef,0x0e,0x00};
	uint16_t crc_dat = 0;
	addr = uart1.rx_buf[3]|uart1.rx_buf[4]<<16;
	buf[4] = uart1.rx_buf[0];
	buf[5] = uart1.rx_buf[1];
	buf[6] = uart1.rx_buf[2];
	buf[7] = uart1.rx_buf[3];
	buf[8] = uart1.rx_buf[4];
	buf[9] = 0x01;
	crc_dat = crc16(&buf[4],6);
	buf[11] = crc_dat&0xff;
	buf[10] = (crc_dat>>8)&0xff;
	buf[12] = 0xfe;
	buf[13] = 0xfe;
	UART1_Send(buf,14);
	if(addr == 0)//如果打开的通道为0，就认为是关闭
	{
		JDQ(0);
		close_num_ad();
	}
	else
	{
		JDQ(0);
		open_num_ad(addr);
	}
}

/***********************************************
函数名称：uart_cmd02
函数参数: 
函数意义：串口接收到02命令，读取数据，需要延迟一秒在提交到上位机，
		采用定时器处理，内部可以对采集的数据进行适当的处理
函数返回ֵ：
*************************************************/
uint32_t read_vdatbuf[200] = {0};
uint32_t read_idatbuf[200] = {0};
static void uart_cmd02(void)
{
	uint16_t i = 0;
	uint8_t buf[20] = {0xef,0xef,0x11,0x00};
	uint16_t crc_dat = 0;
	while(1)//此处等待1S的延时再返回数据。内部做数据读取等处理数据
	{
		feed_wdt();
		for(i=0;i<20;i++)
		{
			read_vdatbuf[i] = read_ads8320_v();//读取电压值
			read_idatbuf[i] = read_ads8320_i();//读取电流值
		}
		feed_wdt();
		read_vdat = Data_Processing(read_vdatbuf,20);
		read_idat = Data_Processing(read_idatbuf,20);
		feed_wdt();
//		delay(1000000);
		break;
	}
	buf[4] = uart1.rx_buf[0];
	buf[5] = uart1.rx_buf[1];
	buf[6] = uart1.rx_buf[2];
	buf[7] = read_vdat&0xff;
	buf[8] = (read_vdat>>8)&0xff;
	buf[9] = read_idat&0xff;
	buf[10] = (read_idat>>8)&0xff;
	buf[11] = uart1.rx_buf[3];
	buf[12] = uart1.rx_buf[4];
	crc_dat = crc16(&buf[4],9);
	buf[14] = crc_dat&0xff;
	buf[13] = (crc_dat>>8)&0xff;
	buf[15] = 0xfe;
	buf[16] = 0xfe;
	UART1_Send(buf,17);
}
/***********************************************
函数名称：uart_cmd03
函数参数: 
函数意义：串口接收到03命令，结束测试，需要关闭所有继电器
函数返回ֵ：
*************************************************/
static void uart_cmd03(void)
{
	uint8_t buf[20] = {0xef,0xef,0x0c,0x00};
	uint16_t crc_dat = 0;
	buf[4] = uart1.rx_buf[0];
	buf[5] = uart1.rx_buf[1];
	buf[6] = uart1.rx_buf[2];
	buf[7] = 0x01;
	crc_dat = crc16(&buf[4],4);
	buf[9] = crc_dat&0xff;
	buf[8] = (crc_dat>>8)&0xff;
	buf[10] = 0xfe;
	buf[11] = 0xfe;
	UART1_Send(buf,12);
	close_num_ad();
	JDQ(0);
}
/***********************************************
函数名称：uart_cmd04
函数参数: 
函数意义：串口接收到04命令，打开内爆继电器
函数返回ֵ：
*************************************************/
static void uart_cmd04(void)
{
	uint8_t buf[20] = {0xef,0xef,0x0e,0x00};
	uint16_t crc_dat = 0;
	buf[4] = uart1.rx_buf[0];
	buf[5] = uart1.rx_buf[1];
	buf[6] = uart1.rx_buf[2];
	buf[7] = 0x01;
	buf[8] = uart1.rx_buf[3];
	buf[9] = uart1.rx_buf[4];
	crc_dat = crc16(&buf[4],6);
	buf[11] = crc_dat&0xff;
	buf[10] = (crc_dat>>8)&0xff;
	buf[12] = 0xfe;
	buf[13] = 0xfe;
	UART1_Send(buf,14);
	JDQ(1);
}
/***********************************************
函数名称：uart_task
函数参数: 
函数意义：串口轮训任务
函数返回ֵ：
*************************************************/

extern uint8_t addr;
void uart_task(void)
{
	uint16_t len = 0,crc = 0;
	if(uart1.flag == 1)
	{
		if(uart1.rx_buf[0] == addr)
		{
			switch(uart1.rx_buf[1])
			{
				case 1:
				case 2:
				case 4:len = 7;break;
				case 3:len = 5;break;
			}
			crc = crc16(uart1.rx_buf,len-2);
			if(crc == (uart1.rx_buf[len-2]<<8|uart1.rx_buf[len-1]))
			{
				switch(uart1.rx_buf[1])
				{
					case 0x01:uart_cmd01();break;
					case 0x02:uart_cmd02();break;
					case 0x03:uart_cmd03();break;
					case 0x04:uart_cmd04();break;
					default:break;
				}
			}
		}
		memset(uart1.rx_buf,0,uart1.rx_len);
		uart1.rx_len = 0;
		uart1.flag = 0;
		
	}
}
